package org.jeecg.modules.login.handler.mail;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Nonnull;
import javax.annotation.Resource;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import javax.mail.util.ByteArrayDataSource;
import java.io.IOException;
import java.util.Objects;

/**
 * 邮件执行器
 *
 * @author tianyi.jiang
 * @since 1.0.0
 */
@Component
public class MailHandler {

    @Value("${spring.mail.username}")
    private String sender;

    @Resource
    private JavaMailSender javaMailSender;

    /**
     * 发送邮件
     *
     * @param entry 邮件信息
     */
    public void send(@Nonnull EntryBuilder entry) {
        SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
        simpleMailMessage.setFrom(sender);
        simpleMailMessage.setSubject(entry.getSubject());
        simpleMailMessage.setTo(entry.getTo());
        simpleMailMessage.setCc(entry.getCc());
        simpleMailMessage.setBcc(entry.getBcc());
        simpleMailMessage.setText(entry.getText());
        javaMailSender.send(simpleMailMessage);
    }

    /**
     * 发送邮件(附件)
     *
     * @param entry          邮件信息
     * @param multipartFiles 附件
     */
    public void send(@Nonnull EntryBuilder entry, @Nonnull MultipartFile... multipartFiles) throws MessagingException, IOException {
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, Boolean.TRUE);
        mimeMessageHelper.setFrom(sender);
        mimeMessageHelper.setSubject(entry.getSubject());
        mimeMessageHelper.setTo(entry.getTo());
        mimeMessageHelper.setText(entry.getText());
        // 抄送人(普通)禁止传递空
        if (ArrayUtils.isNotEmpty(entry.getCc())) {
            mimeMessageHelper.setCc(entry.getCc());
        }
        // 抄送人(盲抄)禁止传递空
        if (ArrayUtils.isNotEmpty(entry.getBcc())) {
            mimeMessageHelper.setBcc(entry.getBcc());
        }
        for (MultipartFile multipartFile : multipartFiles) {
            // 文件名
            String filename = Objects.requireNonNull(multipartFile.getOriginalFilename());
            // 文件流
            ByteArrayDataSource byteArrayDataSource = new ByteArrayDataSource(multipartFile.getInputStream(), MediaType.APPLICATION_OCTET_STREAM_VALUE);
            // 添加附件
            mimeMessageHelper.addAttachment(filename, byteArrayDataSource);
        }
        // 发送
        javaMailSender.send(mimeMessage);
    }

    public MailHandler(JavaMailSender javaMailSender) {
        this.javaMailSender = javaMailSender;
    }

    @Getter
    @ToString
    @NoArgsConstructor
    @AllArgsConstructor
    public static class EntryBuilder {
        /**
         * 主题
         */
        private String subject;
        /**
         * 发送给
         */
        private String[] to;
        /**
         * 抄送给(普通)
         */
        private String[] cc;
        /**
         * 抄送给(盲普通)
         */
        private String[] bcc;
        /**
         * 内容
         */
        private String text;

        public static Builder builder() {
            return new Builder();
        }

        @SuppressWarnings("unused")
        public static class Builder {

            private String subject;

            private String[] to;

            private String[] cc;

            private String[] bcc;

            private String text;

            public Builder subject(String subject) {
                this.subject = subject;
                return this;
            }

            public Builder to(String... to) {
                this.to = to;
                return this;
            }

            public Builder cc(String... cc) {
                this.cc = cc;
                return this;
            }

            public Builder bcc(String... bcc) {
                this.bcc = bcc;
                return this;
            }

            public Builder text(String text) {
                this.text = text;
                return this;
            }

            public EntryBuilder build() {
                return new EntryBuilder(this.subject, this.to, this.cc, this.bcc, this.text);
            }
        }
    }

}
